using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;

namespace Oops.Xna.Framework.Audio
{
	/// <summary>
	/// Implements the <see cref="IAudioService"/> to provide audio capabilities.
	/// </summary>
	public class AudioComponent : GameComponent, IAudioService 
	{
		private AudioEngine audioEngine;

		/// <summary>
		/// Initializes a new instance of the <see cref="AudioComponent"/> class.
		/// </summary>
		/// <param name="game">The <see cref="Microsoft.Xna.Framework.Game"/> that the game component should be attached to.</param>
		public AudioComponent(Game game) : base(game)
		{
			// The game parameter must be specified.
			if (game == null)
			{
				throw new ArgumentNullException("game");
			}
		}

		/// <summary>
		/// Gets or sets location of the XACT global settings file.
		/// </summary>
		public string SettingsFile { get; set; }

		#region IAudioService Members

		public AudioEngine AudioEngine
		{
			get { return this.audioEngine; }
		}

		#endregion

		#region GameComponent Members

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				lock (this)
				{
					// Remove self from the service container.
					if (this.Game.GetService<IAudioService>(false) == this)
					{
						this.Game.RemoveService<IAudioService>(true);
					}

					// Dispose of the audio engine.
					if (this.audioEngine != null)
					{
						this.audioEngine.Dispose();
					}
				}
			}

			// Call inherited method.
			base.Dispose(disposing);
		}

		#endregion

		#region IGameComponent Members

		public override void Initialize()
		{
			// Add self to the service container.
			this.Game.AddService<IAudioService>(this, true);

			// Create and initialize the audio engine.
			this.audioEngine = new AudioEngine(this.SettingsFile);

			// Call inherited method.
			base.Initialize();
		}

		#endregion

		#region IUpdateable Members

		public override void Update(GameTime gameTime)
		{
			// Allow the audio engine to process.
			this.audioEngine.Update();

			// Call inherited method.
			base.Update(gameTime);
		}

		#endregion
	}
}


